package tech.aistar.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tech.aistar.mapper.BookMapper;
import tech.aistar.service.IBookService;

/**
 * 本类用来演示:
 *
 * @author: success
 * @date: 2021/5/7 3:27 下午
 */
@Service
//propagation = Propagation.REQUIRED
//判断当前环境中是否已经有事务了,如果有则直接加入.如果没有,就自己开启一个新的
//@Transactional(propagation = Propagation.REQUIRES_NEW,readOnly = true)//默认的事务的传播行为

//过程
//REQUIRES_NEW
//1. 调用checkout事务方法的时候,开启一个事务T1
//2. 第一次调用事务方法purcase,由于设置了REQUIRES_NEW
//   代表不关心当前环境中是否已经存在事务,它自己会开启一个新的事务T2
//3. 事务T1就会挂起,purcase方法继续执行,如果没有出现异常,当purcase方法执行结束
//   代表着T2事务结束了.

//4. T1事务就会结束挂起状态,T1事务继续

//5. 第二次调用purcase方法,还是会继续开启一个新的事务T3
//6. T3事务一旦开始,原先的checkout对应的事务T1又会挂起
//7. T3事务内部出现了异常,执行事务的回滚操作[意味着事务的结束]

//8. T3事务一旦结束,T1事务继续了

//9. 当checkout方法执行完毕 - T1事务才会结束



//不管当前环境中是否已经开启了事务,永远会新开一个事务.

@Transactional
public class BookServiceImpl implements IBookService {

    //service层调用mapper层...
    @Autowired
    private BookMapper bookMapper;

    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void purcase(String username, int id) {
        //1. 获取id图书的单价
        double price = bookMapper.findBookPriceById(id);

        //2. 更新库存
        bookMapper.updateBookStock(id);

        //模拟意外的发生
        //System.out.println(10/(id-2));

        //3. 更新一下账户的余额
        bookMapper.updateUserAccount(username,price);
    }
}
